package com.eling.elcms.travel.model;

import com.eling.elcms.basedoc.model.EnumSerializer;
import com.eling.elcms.core.dao.annotation.Between;
import com.eling.elcms.core.dao.annotation.CriteriaEnhancer;
import com.eling.elcms.core.dao.annotation.CriteriaEnhancers;
import com.eling.elcms.core.dao.annotation.In;
import com.eling.elcms.core.dao.hibernate.OrderCriteriaEnhancer;
import com.eling.elcms.core.dao.hibernate.search.EnumBridge;
import com.eling.elcms.core.model.BaseModel;
import com.eling.elcms.ordermanager.model.ServicePoint;
import com.eling.elcms.privilege.service.impl.CommonPrivilegeCriteriaEnhancer;
import com.eling.elcms.system.model.CommonUser;
import com.eling.elcms.travel.model.TravelContractCharge.PaymentMethod;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.hibernate.search.annotations.*;

import javax.persistence.*;
import java.util.Date;
import java.util.Set;

/**
 * 散客团信息
 *
 * @author zhoulin
 */
@Entity
@Table(name = "travel_nonmembergroup")
@Indexed
@CriteriaEnhancers(criteriaEnhancers = {
        @CriteriaEnhancer(impl = OrderCriteriaEnhancer.class, parameter = "checkInDate:desc"),
        @CriteriaEnhancer(impl = CommonPrivilegeCriteriaEnhancer.class, parameter = "servicePoint:servicePoint")})
public class NonMemberGroup extends BaseModel {

    private static final long serialVersionUID = -906123877864724584L;

    @Id
    @In
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @DocumentId
    private Long pkNonMemberGroup;

    /**
     * 目的地服务点
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "pkServicePoint")
    @IndexedEmbedded(depth = 1)
    private ServicePoint servicePoint;

    /**
     * 来源类型
     */
    @Enumerated(EnumType.STRING)
    @Field
    @FieldBridge(impl = EnumBridge.class)
    @In
    private SourceType sourceType;

    /**
     * 登记类型
     */
    @Enumerated(EnumType.STRING)
    @Field
    @FieldBridge(impl = EnumBridge.class)
    @In
    private SignUpType signUpType;

    /**
     * 登记人
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "pkUser")
    @IndexedEmbedded(depth = 1)
    private CommonUser operator;

    /**
     * 入住人数
     */
    @Field
    @Column
    private Double perNumber;

    /**
     * 登记日期
     */
    @Field
    @Column
    @Between
    private Date operateDate;

    /**
     * 收费日期
     */
    @Field
    @Column
    @Between
    private Date chargeDate;

    /**
     * 收费方式
     */
    @Enumerated(EnumType.STRING)
    @In
    @FieldBridge(impl = EnumBridge.class)
    private PaymentMethod paymentMethod;

    /**
     * 收费备注
     */
    @Column
    @Field
    private String payDescription;

    /**
     * 入住日期
     */
    @Field
    @Column
    @Between
    private Date checkInDate;

    /**
     * 退住日期
     */
    @Field
    @Column
    @Between
    private Date checkOutDate;

    /**
     * 散客类型
     */
    @Enumerated(EnumType.STRING)
    @Field
    @FieldBridge(impl = EnumBridge.class)
    @In
    private TourType tourType;

    /**
     * 散客团状态
     */
    @Enumerated(EnumType.STRING)
    @Field
    @FieldBridge(impl = EnumBridge.class)
    @In
    private Status status;

    /**
     * 组团单位
     */
    @Column(length = 127)
    @Field
    private String groupUnit;

    /**
     * 是否收取订金
     */
    @Column
    @Field
    private Boolean chargeDeposit;

    /**
     * 订金金额
     */
    @Column
    @Field
    private Double deposit;

    /**
     * 押金金额
     */
    @Column
    @Field
    private Double pledge;


    /**
     * 应收押金金额
     */
    private Double pledgeMoney;
    /**
     * 订金实收
     */
    @Column
    @Field
    private Double money;

    /**
     * 费用状态
     */
    @Column
    @Field
    private Boolean pledgeStatus;

    /**
     * 联系人
     */
    @Column
    @Field
    private String contactName;

    /**
     * 联系人电话
     */
    @Column
    @Field
    private String contactPhone;

    /**
     * 报名信息
     */
    @OneToMany
    @JoinColumn(name = "pkNonMemberGroup")
    @IndexedEmbedded(depth = 1)
    private Set<NonMemberRegister> signUps;

    /**
     * 是否含水电费
     */
    @Column
    @Field
    private Boolean isWaterElectric;

    /**
     * 备注
     */
    @Column
    @Field
    private String description;

    /**
     * 是否调整
     */
    @Column
    @Field
    private Boolean isAdjustment;

    /**
     * 调整日期
     */
    @Column
    @Field
    private Date adjustDate;

    /**
     * 调整类型
     */
    @ElementCollection(fetch = FetchType.LAZY)
    @Enumerated(EnumType.STRING)
    @CollectionTable(name = "travel_nonmem_adjusttypes", joinColumns = @JoinColumn(name = "pkNonMemGroup"))
    @Column(name = "adjusttypes", nullable = false)
    private Set<AdjustType> adjustTypes;

    /**
     * 是否整团取消
     */
    @Column(columnDefinition = "bigint default 0")
    @Field
    private Boolean isAbolished;

    @Version
    private Integer version;

    @JsonSerialize(using = EnumSerializer.class)
    public static enum SourceType {
        Reservation("预约"), DropIn("上门");

        private String display;

        SourceType(String display) {
            this.display = display;
        }

        public String getDisplay() {
            return display;
        }
    }

    @JsonSerialize(using = EnumSerializer.class)
    public static enum SignUpType {
        NonMember("散客"), Experience("体验");

        private String display;

        SignUpType(String display) {
            this.display = display;
        }

        public String getDisplay() {
            return display;
        }
    }

    @JsonSerialize(using = EnumSerializer.class)
    public static enum TourType {
        TravelGroup("旅行团"), Individual("个人"), IndivMember("会员散客");

        private String display;

        TourType(String display) {
            this.display = display;
        }

        public String getDisplay() {
            return display;
        }
    }

    @JsonSerialize(using = EnumSerializer.class)
    public static enum Status {
        Initial("初始"), Effective("有效"), CheckIn("入住"), CheckOut("退住"), Confirm("已确认"), Reserve("已预约"), Cancel("已取消");

        private String display;

        Status(String display) {
            this.display = display;
        }

        public String getDisplay() {
            return display;
        }
    }

    public Integer getSignUpNum() {
        if (signUps != null) {
            return signUps.size();
        } else {
            return 0;
        }
    }

    public Boolean getIsWaterElectric() {
        return isWaterElectric;
    }

    public void setIsWaterElectric(Boolean isWaterElectric) {
        this.isWaterElectric = isWaterElectric;
    }

    public Long getPkNonMemberGroup() {
        return pkNonMemberGroup;
    }

    public void setPkNonMemberGroup(Long pkNonMemberGroup) {
        this.pkNonMemberGroup = pkNonMemberGroup;
    }

    public ServicePoint getServicePoint() {
        return servicePoint;
    }

    public void setServicePoint(ServicePoint servicePoint) {
        this.servicePoint = servicePoint;
    }

    public SignUpType getSignUpType() {
        return signUpType;
    }

    public void setSignUpType(SignUpType signUpType) {
        this.signUpType = signUpType;
    }

    public CommonUser getOperator() {
        return operator;
    }

    public void setOperator(CommonUser operator) {
        this.operator = operator;
    }

    public Date getOperateDate() {
        return operateDate;
    }

    public void setOperateDate(Date operateDate) {
        this.operateDate = operateDate;
    }

    public Date getCheckInDate() {
        return checkInDate;
    }

    public void setCheckInDate(Date checkInDate) {
        this.checkInDate = checkInDate;
    }

    public Date getCheckOutDate() {
        return checkOutDate;
    }

    public void setCheckOutDate(Date checkOutDate) {
        this.checkOutDate = checkOutDate;
    }

    public TourType getTourType() {
        return tourType;
    }

    public void setTourType(TourType tourType) {
        this.tourType = tourType;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public String getGroupUnit() {
        return groupUnit;
    }

    public void setGroupUnit(String groupUnit) {
        this.groupUnit = groupUnit;
    }

    public Boolean getChargeDeposit() {
        return chargeDeposit;
    }

    public void setChargeDeposit(Boolean chargeDeposit) {
        this.chargeDeposit = chargeDeposit;
    }

    public Double getDeposit() {
        return deposit;
    }

    public void setDeposit(Double deposit) {
        this.deposit = deposit;
    }

    public String getContactName() {
        return contactName;
    }

    public void setContactName(String contactName) {
        this.contactName = contactName;
    }

    public String getContactPhone() {
        return contactPhone;
    }

    public void setContactPhone(String contactPhone) {
        this.contactPhone = contactPhone;
    }

    public Set<NonMemberRegister> getSignUps() {
        return signUps;
    }

    public void setSignUps(Set<NonMemberRegister> signUps) {
        this.signUps = signUps;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getVersion() {
        return version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public Date getChargeDate() {
        return chargeDate;
    }

    public void setChargeDate(Date chargeDate) {
        this.chargeDate = chargeDate;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    public PaymentMethod getPaymentMethod() {
        return paymentMethod;
    }

    public void setPaymentMethod(PaymentMethod paymentMethod) {
        this.paymentMethod = paymentMethod;
    }

    public String getPayDescription() {
        return payDescription;
    }

    public void setPayDescription(String payDescription) {
        this.payDescription = payDescription;
    }

    public SourceType getSourceType() {
        return sourceType;
    }

    public void setSourceType(SourceType sourceType) {
        this.sourceType = sourceType;
    }

    public Double getPledge() {
        return pledge;
    }

    public void setPledge(Double pledge) {
        this.pledge = pledge;
    }

    public Boolean getPledgeStatus() {
        return pledgeStatus;
    }

    public void setPledgeStatus(Boolean pledgeStatus) {
        this.pledgeStatus = pledgeStatus;
    }

    public Boolean getIsAdjustment() {
        return isAdjustment;
    }

    public void setIsAdjustment(Boolean isAdjustment) {
        this.isAdjustment = isAdjustment;
    }

    public Date getAdjustDate() {
        return adjustDate;
    }

    public void setAdjustDate(Date adjustDate) {
        this.adjustDate = adjustDate;
    }

    public Set<AdjustType> getAdjustTypes() {
        return adjustTypes;
    }

    public void setAdjustTypes(Set<AdjustType> adjustTypes) {
        this.adjustTypes = adjustTypes;
    }

    public Boolean getIsAbolished() {
        return isAbolished;
    }

    public void setIsAbolished(Boolean isAbolished) {
        this.isAbolished = isAbolished;
    }

    public Double getPledgeMoney() {
        return pledgeMoney;
    }

    public void setPledgeMoney(Double pledgeMoney) {
        this.pledgeMoney = pledgeMoney;
    }

    public Double getPerNumber() {
        return perNumber;
    }

    public void setPerNumber(Double perNumber) {
        this.perNumber = perNumber;
    }

}
